﻿using System;

namespace NodeJS
{
    public class Buffer
    {
        /// <summary>
        /// encoding String The encoding string to test
        /// </summary>
        /// <param name="encoding"></param>
        /// <returns>Returns true if the encoding is a valid encoding argument, or false otherwise.</returns>
        public static bool IsEncoding(string encoding)
        {
            return false;
        }

        /// <summary>
        /// Gives the actual byte length of a string. encoding defaults to 'utf8'.
        /// This is not the same as String.prototype.length since that returns the number of characters in a string.
        /// </summary>
        /// <param name="str"></param>
        /// <param name="encoding">defaults to 'utf8'</param>
        /// <returns></returns>
        public static long ByteLength(string str, string encoding = Encoding.Utf8)
        {
            return 0;
        }

        /// <summary>
        /// Tests if obj is a Buffer.
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static bool IsBuffer(object obj)
        {
            return false;
        }

        /// <summary>
        /// Returns a buffer which is the result of concatenating all the buffers in the list together.
        /// If totalLength is not provided, it is read from the buffers in the list. However, this adds an additional loop to the function, so it is faster to provide the length explicitly.
        /// </summary>
        /// <param name="list"> List of Buffer objects to concat</param>
        /// <param name="totalLength">Number Total length of the buffers when concatenated</param>
        /// <returns></returns>
        public static Buffer Concat(Buffer[] list, int totalLength = 0)
        {
            return null;
        }

        /// <summary>
        /// Allocates a new buffer of size octets.
        /// </summary>
        /// <param name="size"></param>
        public Buffer(long size)
        {
        }

        /// <summary>
        /// Allocates a new buffer using an array of octets.
        /// </summary>
        /// <param name="array"></param>
        public Buffer(byte[] array)
        {
        }

        /// <summary>
        /// Allocates a new buffer containing the given str. encoding defaults to 'utf8'.
        /// </summary>
        /// <param name="str"></param>
        /// <param name="encoding"></param>
        public Buffer(string str, string encoding = Encoding.Utf8)
        {
        }

        /// <summary>
        /// Writes string to the buffer at offset using the given encoding.
        /// If buffer did not contain enough space to fit the entire string, it will write a partial amount of the string.
        ///  The method will not write partial characters.
        /// </summary>
        /// <param name="str">data to be written to buffer</param>
        /// <param name="offset">offset defaults to 0</param>
        /// <param name="length">length is the number of bytes to write. Returns number of octets written.</param>
        /// <param name="encoding">encoding defaults to 'utf8'</param>
        /// <returns> Returns number of octets written.</returns>
        public long Write(string str, long offset = 0, long length = 0, string encoding = Encoding.Utf8)
        {
            return 0;
        }

        /// <summary>
        /// Decodes and returns a string from buffer data encoded with encoding beginning at start and ending at end.
        /// </summary>
        /// <param name="encoding">defaults to 'utf8'</param>
        /// <param name="start">defaults to 0</param>
        /// <param name="end">defaults to buffer.length</param>
        /// <returns></returns>
        public string ToString(string encoding, long start, long end)
        {
            return null;
        }

        /// <summary>
        /// Returns a JSON-representation of the Buffer instance, which is identical to the output for JSON Arrays. JSON.stringify implicitly calls this function when stringifying a Buffer instance.
        /// </summary>
        /// <returns></returns>
        public string ToJSON()
        {
            return null;
        }

        public byte this[long index]
        {
            get { return 0; }
            set { }
        }

        /// <summary>
        /// The size of the buffer in bytes. Note that this is not necessarily the size of the contents. length refers to the amount of memory allocated for the buffer object. 
        /// It does not change when the contents of the buffer are changed.
        /// </summary>
        public int Length;

        /// <summary>
        /// Does copy between buffers. The source and target regions can be overlapped.
        /// All values passed that are undefined/NaN or are out of bounds are set equal to their respective defaults.
        /// </summary>
        /// <param name="targetBuffer">Buffer object - Buffer to copy into</param>
        /// <param name="targetStart">default to 0</param>
        /// <param name="sourceStart">default to 0</param>
        /// <param name="sourceEnd"> defaults to buffer.length</param>
        public void Copy(Buffer targetBuffer, long targetStart = 0, long sourceStart = 0, long sourceEnd = 0)
        {
        }

        /// <summary>
        /// Returns a new buffer which references the same memory as the old, but offset and cropped by the start and end indexes. 
        /// Negative indexes start from the end of the buffer.
        /// Modifying the new buffer slice will modify memory in the original buffer!
        /// </summary>
        /// <param name="start">defaults to 0</param>
        /// <param name="end">defaults to buffer.length</param>
        public void Slice(long start = 0, long end = 0)
        { 
        }

        /// <summary>
        /// Fills the buffer with the specified value. If the offset (defaults to 0) and end (defaults to buffer.length) are not given it will fill the entire buffer.
        /// </summary>
        /// <param name="val"></param>
        /// <param name="offset">defaults to 0</param>
        /// <param name="end">defaults to buffer.length</param>
        public void Fill(char val, int offset = 0, int end = 0) 
        { 
        }

        //TODO:Read family
        //TODO:Write family
    }
}
